package com.kaoqin.code.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PropertiesUtils {
	public static Log _log = LogFactory.getLog(PropertiesUtils.class);
	private static List _paths = new ArrayList();
	private static Properties _p = null;
	private static Properties _db_p = null;
	private static PropertiesUtils _pu = new PropertiesUtils();
	private static final String SYSTEM_PROPERTIES_PATH = "system.properties";
	private static final Date SYSTEM_START_TIME = new Date();
	private static String port = "";
	private static String serverRealPath = "";

	private PropertiesUtils() {
		Properties p = new Properties();
		ClassLoader classLoader = PropertiesUtils.class.getClassLoader();
		// system.properties
		_log.info("开始加载" + SYSTEM_PROPERTIES_PATH);
		InputStream is = null;
		try {
			URL url = classLoader.getResource(SYSTEM_PROPERTIES_PATH);
			if (url != null) {
				is = url.openStream();
				p.load(is);
				_log.debug("Loading " + url);
				_paths.add(SYSTEM_PROPERTIES_PATH);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		_p = p;
		_log.info("加载Properties配置文件完成");
	}
	/**
	 * 判断指定配置文件是否已经加载
	 * @param propertiesPath
	 * @return
	 */
	public static boolean hasLoaded(String propertiesPath) {
		return _paths.contains(propertiesPath);
	}
	/**
	 * 加载指定文件的配置
	 * @param propertiesPath
	 */
	public static void loadProperties(String propertiesPath) {
		if (hasLoaded(propertiesPath)) {
			return;
		}
		ClassLoader classLoader = PropertiesUtils.class.getClassLoader();
		try {
			URL url = classLoader.getResource(propertiesPath);
			if (url != null) {
				InputStream is = url.openStream();
				_pu._p.load(is);
				is.close();
				_log.debug("Loading " + url);
				_paths.add(propertiesPath);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 返回配置中字符串形式
	 * @param key
	 * @return
	 */
	public static String get(String key) {
		return get(key, null);
	}
	/**
	 * 返回一个整形配置
	 * @param key
	 * @return
	 */
	public static Integer getInt(String key) {
		String val = get(key, null);
		return val != null ? Integer.valueOf(val) : null;
	}
	/**
	 * 返回一个长整形配置
	 * @param key
	 * @return
	 */
	public static Long getLong(String key) {
		String val = get(key, null);
		return val != null ? Long.valueOf(val) : null;
	}
	/**
	 * 返回配置中逗号分隔形式的数组形式
	 * @param key
	 * @return
	 */
	public static String[] getArrayUTF8(String key) {
		String value = getUTF8(key, null);
		if (value == null) {
			return null;
		} else {
			return value.split(",");
		}
	}
	/**
	 * 返回配置中逗号分隔形式的数组形式
	 * @param key
	 * @return
	 */
	public static String[] getArray(String key) {
		String value = get(key, null);
		if (value == null) {
			return null;
		} else {
			return value.split(",");
		}
	}
	/**
	 * 获得布尔类型的配置，其中处理人true、y、1的配置，忽略大小写
	 * @param key
	 * @return
	 */
	public static Boolean getBoolean(String key) {
		String val = get(key, null);
		if (val == null) {
			return null;
		}
		val = val.toLowerCase();
		if ("true".equals(val) || "y".equals(val) || "1".equals(val)) {
			return new Boolean(true);
		}
		return new Boolean(false);
	}
	public static String getUTF8(String key, String defaultVal) {
		String val = getPropertieForDB(key);
		if (val == null) {
			val = _pu._p.getProperty(key);
		}
		if (val == null || "".equals(val)) {
			return defaultVal;
		}
		try {
			return new String(val.getBytes("ISO-8859-1"), "utf-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
	/**
	 * 返回配置中字符串形式，优先读取动态Properties配置
	 * @param key key
	 * @param defaultVal 默认值
	 * @return
	 */
	public static String get(String key, String defaultVal) {
		String val = getPropertieForDB(key);
		if (val == null) {
			val = _pu._p.getProperty(key);
		}
		if (val == null || "".equals(val)) {
			return defaultVal;
		}
		return val;
	}
	/**
	 * 返回一个整形配置
	 * @param key key
	 * @param defaultVal 默认值
	 * @return
	 */
	public static int getInt(String key, int defaultVal) {
		String val = get(key, defaultVal + "");
		return Integer.parseInt(val);
	}
	/**
	 * 返回一个长整形配置
	 * @param key key
	 * @param defaultVal 默认值
	 * @return
	 */
	public static long getLong(String key, long defaultVal) {
		String val = get(key, defaultVal + "");
		return Long.parseLong(val);
	}
	/**
	 * 返回配置中逗号分隔形式的数组形式
	 * @param key key
	 * @param defaultVal 默认值
	 * @return
	 */
	public static String[] getArray(String key, String[] defaultVal) {
		String value = get(key);
		if (value == null || "".equals(value)) {
			return defaultVal;
		} else {
			return value.split(",");
		}
	}
	/**
	 * 获得布尔类型的配置，其中处理人true、y、1的配置，忽略大小写
	 * @param key key
	 * @param defaultVal 默认值
	 * @return
	 */
	public static boolean getBoolean(String key, boolean defaultVal) {
		String val = get(key, defaultVal + "");
		val = val.toLowerCase();
		if ("true".equals(val) || "y".equals(val) || "1".equals(val)) {
			return true;
		}
		return false;
	}
	public static Properties getProperties() {
		return _pu._p;
	}
	// 读取配置文件中的配置
	public static String getProertieForFile(String key) {
		String val = _pu._p.getProperty(key);
		if (val != null) {
			try {
				return new String(val.getBytes("ISO-8859-1"), "utf-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return null;
	}
	// 读取动态配置
	public static String getPropertieForDB(String key) {
		if (_db_p == null) {
			return null;
		}
		return _db_p.getProperty(key);
	}
	// 设置动态配置
	public static void setPropertieForDB(String key, String value) {
		if (_db_p == null) {
			_db_p = new Properties();
		}
		_db_p.setProperty(key, value);
	}
	public static void init() {
	}
	// 获取系统启动时间
	public static Date getSystemStartTime() {
		return SYSTEM_START_TIME;
	}
	public static String getServerRealPath() {
		return PropertiesUtils.serverRealPath;
	}
	public static void setServerRealPath(String serverRealPath) {
		PropertiesUtils.serverRealPath = serverRealPath;
	}
	// 动态设置Properties配置
	public static void setProperty(String key, String value) {
		PropertiesUtils._p.setProperty(key, value);
	}
	public static String getHttpPort(String protocol, String scheme) throws Exception {
		if ("".equals(port)) {
			MBeanServer mBeanServer = null;
			if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
				mBeanServer = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
			}
			Set names = null;
			try {
				names = mBeanServer.queryNames(new ObjectName("*:type=Connector,*"), null);
			} catch (Exception e) {
				e.printStackTrace();
			}
			Iterator it = names.iterator();
			ObjectName oname = null;
			while (it.hasNext()) {
				oname = (ObjectName) it.next();
				String pvalue = "";
				try {
					pvalue = (String) mBeanServer.getAttribute(oname, "protocol");
				} catch (Exception e) {
					//e.printStackTrace();
				}
				if (pvalue == null || "".equals(pvalue)) {//Tongweb 不支持protocol
					String defaultHost = "";
					try {
						defaultHost = (String) mBeanServer.getAttribute(oname, "defaultHost");
					} catch (Exception e) {
						//e.printStackTrace();
					}
					pvalue = "admin".equals(defaultHost) ? "" : "HTTP/1.1";
				}
				String svalue = "";
				try {
					svalue = (String) mBeanServer.getAttribute(oname, "scheme");
				} catch (Exception e) {
					//e.printStackTrace();
				}
				if (protocol.equals(pvalue) && scheme.equals(svalue)) {
					port = ((Integer) mBeanServer.getAttribute(oname, "port")).toString();
					break;
				}
			}
		}
		return port;
	}
}
